#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    Board board = Unknown;
    inputMode = cameraMode;

    QPixmap splashScreenImage(SICHUAN_UNIVERSITY_BIG);

    QSplashScreen *splashScreen = new QSplashScreen(splashScreenImage);
    splashScreen->setAttribute(Qt::WA_DeleteOnClose, true);
    font.setPointSize(18);
    splashScreen->setFont(font);
    splashScreen->show();
    splashScreen->showMessage("Loading the SCU APP", Qt::AlignCenter, Qt::blue);
    qApp->processEvents();

    iterations = 1;

    ui->setupUi(this);
    this->resize(APP_WIDTH, APP_HEIGHT);
    scene = new QGraphicsScene(this);
    ui->graphicsView->setScene(scene);
    ui->graphicsView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    ui->graphicsView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

    scene_face = new QGraphicsScene(this);
    ui->graphicsView_2->setScene(scene_face);
    ui->graphicsView_2->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    ui->graphicsView_2->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

    connect(this, SIGNAL(sendMatToDraw_2(cv::Mat)), this, SLOT(drawMatToView_2(cv::Mat)));
    connect(this, SIGNAL(sendMatToDraw(cv::Mat)), this, SLOT(drawMatToView(cv::Mat)));

    QPixmap SCULogo;
    SCULogo.load(SICHUAN_UNIVERSITY);
    ui->SCULogo->setPixmap(SCULogo);

    qRegisterMetaType<QVector<float> >("QVector<float>");

    QSysInfo systemInfo;
    if (systemInfo.machineHostName() == "smarc-rzg2l" || systemInfo.machineHostName() == "gx-qsb-rzg2l") {
            setWindowTitle("SiChuan University App");
            boardInfo = G2L_HW_INFO;
            board = G2L;
            cameraLocation = QString("/dev/video0");
     }

    qRegisterMetaType<cv::Mat>();
    cvWorker = new my_opencv(cameraLocation, board);

    splashScreen->close();

    if (cvWorker->cameraInit() == false) {
        qWarning("Camera not initialising. Quitting.");

    } else if (cvWorker->getCameraOpen() == false) {
        qWarning("Camera not opening. Quitting.");

    } else {
        createVideoWorker();
        createFaceWorker();
        vidWorker->StartVideo();
    }
}

void Widget::createVideoWorker()
{
    vidWorker = new videoplay();

    connect(vidWorker, SIGNAL(showVideo()), this, SLOT(ShowVideo()));
    connect(vidWorker, SIGNAL(showVideo2()), this, SLOT(Face_Find_Recognize()));
}

void Widget::createFaceWorker()
{
    faceWorker = new FaceDiscern();
}

void Widget::drawMatToView(const cv::Mat& matInput)
{
    QImage imageToDraw;

    imageToDraw = matToQImage(matInput);

    image = QPixmap::fromImage(imageToDraw);
    scene->clear();

    if (inputMode != cameraMode)
        image = image.scaled(800, 600);

    scene->addPixmap(image);
    scene->setSceneRect(image.rect());
}

void Widget::drawMatToView_2(const cv::Mat& matInput)
{
    QImage imageToDraw;

    imageToDraw = matToQImage(matInput);

    image_face = QPixmap::fromImage(imageToDraw);
    scene_face->clear();

    if (inputMode != cameraMode)
        image_face = image_face.scaled(800, 600);

    scene_face->addPixmap(image_face);
    scene_face->setSceneRect(image_face.rect());
}

void Widget::getImageFrame()
{
    emit sendMatToDraw(*cvWorker->getImage(1));
}

void Widget::ShowVideo()
{
    const cv::Mat* image;

    image = cvWorker->getImage(1);

    if (image == nullptr) {
        qWarning("Camera no longer working. Quitting.");
    } else {
        emit sendMatToDraw(*image);
    }
}

QImage Widget::matToQImage(const cv::Mat& matToConvert)
{
    QImage convertedImage;

    if (matToConvert.empty())
        return QImage(nullptr);

    convertedImage = QImage(matToConvert.data, matToConvert.cols,
                     matToConvert.rows, int(matToConvert.step),
                        QImage::Format_RGB888).copy();

    return convertedImage;
}

void Widget::Face_Find_Recognize()
{
    bool face_find_flag = false;
    Mat image_per_frame;
    vector<Mat> image_faces;
    vector<int> face_num_result;

    cout << endl;
    cout <<"/-----------------------------------------------------------/" << endl;
    qWarning("Start face find");

    image_per_frame = *cvWorker->getImage(1);
    face_find_flag = faceWorker->face_find(image_per_frame, image_faces);
    if(face_find_flag == true){
        ui->train_label->setText("detect success");
        qWarning("find face success");
    }else{
        ui->train_label->setText("detect failed");
        qWarning("find face failed");
    }

    emit sendMatToDraw_2(image_per_frame);

    cout << endl;
    qWarning("Start face recognize");
    face_num_result = faceWorker->face_predict(image_faces);
    cout << "find face:";
    if(!face_num_result.empty()){
        for(long unsigned int i = 0;i < face_num_result.size();i++){
            cout << face_num_result[i] << endl;
            switch(face_num_result[i]){
            case 0:
                ui->name_label->setText("wanheng");
                break;
            case -1:
                ui->name_label->setText("no register");
                break;
            default: break;
            }
        }
    }else{
        ui->name_label->setText("no face");
    }
    cout <<"/-----------------------------------------------------------/" << endl;
}

void Widget::on_Cam_Open_clicked()
{
    vidWorker->StartVideo();
    vidWorker->StopVideo_2();
    scene_face->clear();
    ui->graphicsView_2->setScene(scene_face);
}

void Widget::on_Cam_Close_clicked()
{
    vidWorker->StopVideo();
    scene->clear();
    ui->graphicsView->setScene(scene);
}

void Widget::on_Face_Train_Button_clicked()
{
    bool train_flag = false;

    vidWorker->StopVideo();
    scene->clear();
    ui->graphicsView->setScene(scene);

    train_flag = faceWorker->face_train(faceWorker->index_filename);
    if(train_flag == true){
        ui->train_label->setText("Train success");
        vidWorker->StartVideo();
    }else{
        ui->train_label->setText("Train failed");
    }
}

void Widget::on_ModelUpdateButton_clicked()
{

}

void Widget::on_Face_Rec_On_clicked()
{
    vidWorker->StartVideo_2();
    vidWorker->StopVideo();
    scene->clear();
    ui->graphicsView->setScene(scene);
}

void Widget::on_Face_Rec_Close_clicked()
{
    vidWorker->StopVideo_2();
    scene_face->clear();
    ui->graphicsView_2->setScene(scene_face);
}

Widget::~Widget()
{
    delete ui;
}









